package com.hmdp.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.hmdp.dto.UserDTO;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;


//当访问一个不需要经过拦截器的网页时,token就无法实时刷新,在此我们定义两个拦截器,一个用于token刷新,用于所有请求
//另一个用于验证用户是否存在,范围是需要验证用户的请求
public class RefreshTokenInterceptor implements HandlerInterceptor {

    //这里不能依赖注入,因为这个类不是spring创建的,本身拦截器的执行是在Spring执行之前的,这里使用一种特殊技巧构造出来
    private StringRedisTemplate stringRedisTemplate;

    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    //无参构造函数
    public RefreshTokenInterceptor() {

    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("authorization");
        if(StrUtil.isBlank(token)){
            // 直接放行---这样ThreadLocal中就不会有保存user数据,也是可以拦截
            return  true;
        }
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(RedisConstants.LOGIN_USER_KEY + token);
            // 直接放行---这样ThreadLocal中就不会有保存user数据,也是可以拦截否存在user
        if(userMap.isEmpty()){
            // 直接放行
            return  true;
        }
        //将userMap转换为userDTO类型
        UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
        //存在,保存用户信息到ThreadLocal----LoginInterceptor需要验证是否有userDto存在
        UserHolder.saveUser(userDTO);
        //刷新token有效期---这个拦截器的主要功能就是刷新token
        stringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY + token,RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);
        //放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //移除用户
        UserHolder.removeUser();
    }
}
